<template>
  <view class="word-wrapper" :style="{ overflow: showPopup ? 'hidden' : 'auto' }">
    <view class="word-content" v-if="!props.question.user_voice">
      <view class="word-label">请朗读短语或句子练习发音</view>
      <sentence class="word-sentence" :sentence="wordSentence" />
      <loudspeaker class="word-loudspeaker" isAutoPlay :voice="props.question.us_voice" />
    </view>

    <view class="evaluate-container" v-else>
      <view class="evaluate-score">
        <view class="score-wrapper">
          <view class="score-analyze">
            <view class="score">{{ props.question.score }}</view>
            <view class="analyze" @click="handlePopUp">音素分析</view>
          </view>
          <view class="score-content" v-if="Array.isArray(evaluate.analysis.wordsDetail)">
            <wordNote v-for="(item, index) in evaluate.analysis.wordsDetail" :key="index + item.lab" :word="item" />

            <image class="tonescore-image" :src="evaluate.analysis.wordsDetail.slice(-1).tonescore == 1
    ? 'https://rwstatic.tentons.cn/web/Lesson/images/tonescore-up.png'
    : 'https://rwstatic.tentons.cn/web/Lesson/images/tonescore-down.png'
    " />
          </view>
        </view>
        <view class="score-desc">
          <view class="desc-item mr ml">
            <view class="desc-tag awesome"></view>
            <text class="desc-label">Awesome</text>
          </view>
          <view class="desc-item mr">
            <view class="desc-tag good"></view>
            <text class="desc-label">Good</text>
          </view>
          <view class="desc-item mr">
            <view class="desc-tag average"></view>
            <text class="desc-label">Average</text>
          </view>
          <view class="desc-item mr">
            <view class="desc-tag wrong"></view>
            <text class="desc-label">Wrong</text>
          </view>
          <view class="desc-item mr ml">
            <view class="desc-stress"></view>
            <text class="desc-label">stress</text>
          </view>
          <view class="desc-item mr">
            <image class="desc-image" src="https://rwstatic.tentons.cn/web/Lesson/images/tonescore-up.png" />
            <text class="desc-label">rising intonation</text>
          </view>
          <view class="desc-item">
            <image class="desc-image" src="https://rwstatic.tentons.cn/web/Lesson/images/tonescore-down.png" />
            <text class="desc-label">falling intonation</text>
          </view>
        </view>
      </view>
      <view class="evaluate-sentence">
        <view class="evaluate-sentence-wrapper">
          <view class="sentence-title">整句分析</view>
          <view class="sentence-row">
            <view class="col-content">
              <text class="score">{{ evaluate.analysis.fluency_overall }}</text>
              <text class="desc">流利度</text>
            </view>
            <view class="col-content">
              <text class="score">{{ evaluate.analysis.integrity }}</text>
              <text class="desc">完整度</text>
            </view>
            <view class="col-content">
              <text class="score">{{ evaluate.analysis.accuracy ? evaluate.analysis.accuracy : "— —" }}</text>
              <text class="desc">准确度</text>
            </view>
          </view>

          <view class="sentence-title">朗读分析</view>
          <view class="sentence-info">
            <view class="info-list">
              <view class="list-label">录音</view>
              <loudspeaker class="list-speaker" :voice="evaluate.user_voice" />
            </view>
            <view class="info-list" v-for="item in infoList" :key="item.id">
              <view class="list-label">{{ item.label }}</view>
              <view :class="['list-desc', [1, 2, 3].includes(item.id) && item.desc !== '无' ? 'error' : '']">
                {{ item.desc }}
              </view>
            </view>
          </view>
          <view class="h12"></view>
          <image class="sentence-status" src="https://rwstatic.tentons.cn/web/Lesson/images/sentence-end-status.png" />
          <view class="h20"></view>
          <view class="tag"></view>
        </view>
      </view>
      <view class="evaluate-line"></view>

      <uni-popup ref="popupRef" type="bottom" :safe-area="false" :mask-click="false">
        <view class="evaluate-popup-content">
          <image class="popup-close" src="https://rwstatic.tentons.cn/web/Lesson/images/close-icon.png"
            @click="handleClosePopup" />
          <view class="popup-title">
            音素分析
            <text class="popup-title-label">点击单词切换查看音素详细解析</text>
          </view>
          <view class="popup-words">
            <view class="word" v-for="(item, index) in evaluate.analysis.wordsDetail" :key="index + item.lab"
              @click="handleActiveWord(item, index)">
              <wordNote :word="item" :show-score="false" :show-under-line="false"
                :show-active="activeIndex === index ? true : false" />
            </view>
          </view>
          <view class="popup-sound">
            <view class="sound-row">
              标准发音：{{ standardWord.word }}
              <text class="sound">{{ standardWord.sound }}</text>
            </view>
            <view class="sound-row">
              你的发音：{{ userWord.word }}
              <rich-text class="sound" :nodes="userWord.sound"></rich-text>
            </view>
          </view>
          <view class="popup-label">
            <view class="label-item" v-for="item in labelList" :key="item.label">
              <view :class="['label-tag', item.label]"></view>
              <text class="label-text">{{ item.label }}</text>
            </view>
          </view>
          <view class="popup-line"></view>
        </view>
      </uni-popup>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import sentence from "@/components/sentence.vue";
import wordNote from "@/pages/lowPricedCourse/situationalDialog/scoreResult/wordNote.vue";
import loudspeaker from "@/components/loudspeaker.vue";
import { startEvaluating } from "@/utils/chivox";
// @ts-ignore
import { ossDownLoad } from "@/utils/oss/oss.js";
import API from "@/api";
import { util } from "@/utils/util";
import type { IPracticeList } from "./index";

interface IProps {
  question: IPracticeList;
}

interface IEvaluate {
  [x: string]: any;
}

const emits = defineEmits<{
  (e: "update", payload: any): void;
}>();

const fs = uni.getFileSystemManager();
const props = defineProps<IProps>();

const wordSentence = ref({
  mark: {
    begin: "<b>",
    end: "</b>",
  },
  content: "",
});
const showPopup = ref(false);
const evaluate = ref<IEvaluate>({
  analysis: {
    wordsDetail: [],
  },
});
const activeIndex = ref(0);
const standardWord = ref({
  word: "",
  sound: "",
});
const userWord = ref({
  word: "",
  sound: [],
});
const labelList = ref([
  {
    label: "Awesome",
  },
  {
    label: "Good",
  },
  {
    label: "Average",
  },
  {
    label: "Wrong",
  },
]);
const popupRef = ref<any>(null);
const infoList = ref([
  {
    id: 1,
    label: "多读",
    desc: "",
  },
  {
    id: 2,
    label: "漏读",
    desc: "",
  },
  {
    id: 3,
    label: "错读",
    desc: "",
  },
  {
    id: 4,
    label: "停顿次数",
    desc: "",
  },
  {
    id: 5,
    label: "录音语速",
    desc: "",
  },
]);

const handleSetInfoList = (analysisInfo: any) => {
  infoList.value[0].desc = analysisInfo.readMore.length ? analysisInfo.readMore.join() : "无";
  infoList.value[1].desc = analysisInfo.MissedRead.length ? analysisInfo.MissedRead.join() : "无";
  infoList.value[2].desc = analysisInfo.misread.length ? analysisInfo.misread.join() : "无";
  infoList.value[3].desc = analysisInfo.fluency_pause ? `${analysisInfo.fluency_pause}次` : "无";
  infoList.value[4].desc = analysisInfo.fluency_speed ? `${analysisInfo.fluency_speed}词/分钟` : "无";
}

// 基础课音素修复
const handleRepairPhoneme = async (item: any) => {
  return new Promise<void>((resolve, reject) => {
    util.showLoading();

    ossDownLoad(item.user_voice, false).then((oss: { data: any; }) => {
      fs.readFile({
        filePath: oss.data,
        success: (file) => {
          startEvaluating({
            evaluatingInfo: { sentence: item.practice, isPhoneme: true },
            audioBuffer: file.data as ArrayBuffer,
            onSuccess: (eva) => {
              API.skillRepair({
                record_id: item.record_id,
                analysis: JSON.stringify(eva),
              }).then(async res => {
                evaluate.value = res;
                emits("update", res);

                util.hideLoading();
                resolve();
              })
            },
            onError: (errMsg) => {
              console.log(errMsg);
              util.showDialogue(errMsg);
              util.hideLoading();

              reject();
            },
          })
        },
        fail: (errMsg) => {
          console.log(errMsg);
          util.hideLoading();
          util.showDialogue("找不到音频文件");
          reject();
        }
      })
    })
  })
}

const handleSetStandardWord = (word: { phone_str: string; char: string; phone: any[] }) => {
  standardWord.value.sound = word.phone_str;
  standardWord.value.word = word.char;
  userWord.value.word = word.char;

  let soundColor = "";
  let childrenNodes: any[] = [
    {
      name: "span",
      attrs: {
        class: "rich-text_tag",
      },
      children: [
        {
          type: "text",
          text: "[",
        },
      ],
    },
  ];
  word.phone.forEach((item) => {
    if (item.score >= 0 && item.score <= 40) {
      soundColor = "rich-text_040";
    } else if (item.score >= 41 && item.score <= 59) {
      soundColor = "rich-text_4159";
    } else if (item.score >= 60 && item.score <= 79) {
      soundColor = "rich-text_6079";
    } else if (item.score >= 80 && item.score <= 100) {
      soundColor = "rich-text_80100";
    }

    childrenNodes.push({
      name: "span",
      attrs: {
        class: soundColor,
      },
      children: [
        {
          type: "text",
          text: item.char,
        },
      ],
    });
  });

  childrenNodes.push({
    name: "span",
    attrs: {
      class: "rich-text_tag",
    },
    children: [
      {
        type: "text",
        text: "]",
      },
    ],
  });

  userWord.value.sound = [
    {
      name: "div",
      attrs: {
        class: "rich-text_sentence",
      },
      children: childrenNodes,
    },
  ] as any;
};

const handlePopUp = async () => {
  if (!(Array.isArray(evaluate.value.analysis.phoneme) && evaluate.value.analysis.phoneme.length)) {
    await handleRepairPhoneme(evaluate.value);
  }

  const phoneme = evaluate.value.analysis.phoneme;
  if (!phoneme || !phoneme.length) {
    return;
  }

  handleSetStandardWord(phoneme[0]);

  showPopup.value = true;
  popupRef.value?.open("bottom");
};

const handleClosePopup = () => {
  showPopup.value = false;
  popupRef.value?.close();
};

const handleActiveWord = (item: any, index: number) => {
  if (item.type === 2) {
    return;
  }
  activeIndex.value = index;

  const phoneme = evaluate.value.analysis.phoneme;
  const curWord = phoneme.find((val: { char: string }) => val.char.toLocaleLowerCase() === item.lab.toLocaleLowerCase());
  handleSetStandardWord(curWord);
};

watch(() => props.question, (val) => {
  if (val && val.practice) {
    evaluate.value = val;
    wordSentence.value = {
      mark: {
        begin: "<b>",
        end: "</b>",
      },
      content: val.tag_practice,
    }
    val.analysis && handleSetInfoList(val.analysis);
  }
}, {
  deep: true,
  immediate: true,
})
</script>

<style scoped lang="scss">
@import "./common.scss";

.word-wrapper {
  width: 100%;
  height: 100%;

  .word-content {
    width: 100%;

    .word-label {
      margin-left: 2rem;
      margin-bottom: 11.3rem;
      font-size: 1.6rem;
      font-family: xiaolai;
      color: $uni-text-color;
    }

    .word-sentence {
      display: block;
      margin-left: 2.3rem;
      margin-right: 2.7rem;
      font-size: 2.2rem;
      font-family: baloo;
    }

    .word-loudspeaker {
      display: block;
      margin: 0 auto;
      width: 3.1rem;
      height: 3.1rem;
    }
  }
}
</style>